package com.centerm.bluetooth.ibridge;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.centerm.bluetooth.ibridge.constants.BondStatus;
import com.centerm.bluetooth.ibridge.constants.ConnectMode;
import com.centerm.bluetooth.ibridge.listener.DataReceiver;
import com.centerm.bluetooth.ibridge.listener.EventReceiver;
import com.centerm.util.Logger;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * This class includes: <br>
 * &nbsp&nbsp<b>a,</b> Some basic BT operations. Such as discovering remote
 * devices, pairing with a remote device, set local BT device name, and so on.<br>
 * &nbsp&nbsp<b>b,</b> Operations of connecting and disconnecting remote device.<br>
 * &nbsp&nbsp<b>c,</b> Registration of callback interfaces that must be
 * implements by application to receive Bluetooth Event and data from remote
 * device.<br>
 */
public class BluetoothIBridgeAdapter {

    static final String TAG = "BluetoothIBridgeAdapter";
    static final String VERSION_CODE = "iBridge_version1.1.0_2015.07.06";

    static final String LAST_CONNECTED_DEVICE = "last_connected_device";
    static final String LAST_CONNECTED_DEVICE_NAME = "last_connected_device_name";
    static final String LAST_CONNECTED_DEVICE_ADDRESS = "last_connected_device_address";

    static final int MESSAGE_DEVICE_FOUND = 0;
    static final int MESSAGE_DISCOVERY_FINISHED = 1;
    static final int MESSAGE_DEVICE_BONDED = 2;
    static final int MESSAGE_DEVICE_CONNECTED = 3;
    static final int MESSAGE_DEVICE_DISCONNECTED = 4;
    static final int MESSAGE_DEVICE_CONNECT_FAILED = 5;
    static final int MESSAGE_WRITE_FAILED = 6;

    private BluetoothAdapter mAdapter = null;
    private static BluetoothIBridgeAdapter sAdapter = null;
    private boolean mDiscoveryOnlyBonded = false;
    private Context mContext = null;
    private MyHandler mHandler = null;
    private boolean isEnable = false;
    private boolean isAutoWritePincode = true;
    private String devicePattern = ".*";

    private BluetoothIBridgeConnManager mConnManager = null;
    private ArrayList<EventReceiver> mEventReceivers;
    private final BroadcastReceiver mReceiver;


    /**
     * Register an EventReceiver,the receiver will be called when a Bluetooth
     * event occurs.
     *
     * @param receiver the EventReceiver receiver which wants to receive bluetooth
     *                 events.
     */
    public synchronized void registerEventReceiver(EventReceiver receiver) {
        if (mEventReceivers == null) {
            mEventReceivers = new ArrayList<>();
        }
        if (!mEventReceivers.contains(receiver)) {
            mEventReceivers.add(receiver);
        }
    }

    /**
     * Unregister a previously registered EventReceiver.
     *
     * @param receiver the EventReceiver to be unregistered.
     */
    public synchronized void unregisterEventReceiver(EventReceiver receiver) {
        if (mEventReceivers == null) {
            return;
        }
        mEventReceivers.remove(receiver);
    }


    /**
     * Register an DataReceiver,the receiver will be called when data received.
     *
     * @param receiver the DataReceiver which wants to receive data from remote
     *                 devices.
     */
    public synchronized void registerDataReceiver(DataReceiver receiver) {
        if (mConnManager != null) {
            mConnManager.registerDataReceiver(receiver);
        }
    }

    /**
     * Unregister a previously registered DataReceiver.
     *
     * @param receiver the DataReceiver to be unregistered.
     */
    public synchronized void unregisterDataReceiver(DataReceiver receiver) {
        if (mConnManager != null) {
            mConnManager.unregisterDataReceiver(receiver);
        }
    }

    /**
     * Get singleton BluetoothIBridgeAdapter object instance
     *
     * @param context Android context the BluetoothIBridgeAdapter is running in. It
     *                can be an Activity object or an Application context object.
     * @return a BluetoothIBridgeAdapter object
     */
    public synchronized static BluetoothIBridgeAdapter getDefaultAdapter(Context context) {
        if (sAdapter == null)
            sAdapter = new BluetoothIBridgeAdapter(context);
        return sAdapter;
    }

    /**
     * Constructor.Construct a BluetoothIBridgeAdapter object.Please use
     * {@link #isEnabled()} to check Bluetooth ,if Bluetooth is disabled ,use
     *
     * @param context Android context the BluetoothIBridgeAdapter is running in. It
     *                can be an Activity object or an Application context object.
     */
    private BluetoothIBridgeAdapter(Context context) {
        if (sAdapter != null) {
            sAdapter.destroy();
        }
        mContext = context;
        mHandler = new MyHandler(this);
        mAdapter = BluetoothAdapter.getDefaultAdapter();//????豸????????????
        mConnManager = new BluetoothIBridgeConnManager(mHandler);//????????豸?б?
        setEnabled(true);
        syncSmartConnectModes(null);//????в??  ????????д?????
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothIBridgeDevice.ACTION_PAIRING_REQUEST);
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);// ???ù????????

        mReceiver = new InetBroadcastReceiver();
        mContext.registerReceiver(mReceiver, intentFilter);// ????????????????????????????
        sAdapter = this;
    }

    /***********************************************/
    /*************** SPP Interface ******************/
    /***********************************************/

    /**
     * Directly return the bonded devices, without discovery
     *
     * @return the bonded devices
     */
    public Set<BluetoothIBridgeDevice> getBondedDevices() {
        Set<BluetoothDevice> devList = mAdapter.getBondedDevices();
        Set<BluetoothIBridgeDevice> idevList = new HashSet<>(devList.size());
        for (BluetoothDevice dev : devList) {
            idevList.add(BluetoothIBridgeDeviceFactory.getDefaultFactory().createDevice(dev));
        }
        return idevList;
    }

    /**
     * Call this method to start the discovery procedure. The discovery
     * procedure is long-time execution. When a remote device has been found,
     * the registered EventReceiver <b>onDeviceFound </b> method will be called.
     * When the discovery procedure ends, the registered EventReceiver
     * <b>onDiscoveryFinished</b> method will be called.
     *
     * @param onlyBonded true if only discover the bonded devices,false otherwise.
     */
    public void startDiscovery(boolean onlyBonded) {
        if (isEnabled()) {
            if (mAdapter != null) {
                mDiscoveryOnlyBonded = onlyBonded;
                if (mAdapter.isDiscovering()) {
                    mAdapter.cancelDiscovery();
                }
                mAdapter.startDiscovery();
            }
        }
    }

    /**
     * Call this method to start the discovery procedure. The discovery
     * procedure is long-time execution. Under Android4.3 ,it can only discover
     * classic bluetooth device. Above android 4.4, it can discover both classic
     * and Le device. When a remote device has been found, the registered
     * EventReceiver??s <b>onDeviceFound</b> method will be called. When the
     * discovery procedure ends, the registered EventReceiver??s
     * <b>onDiscoveryFinished</b> method will be called.
     */
    public void startDiscovery() {
        startDiscovery(false);
    }

    /**
     * Call this method to stop the discovery procedure.
     */
    public void stopDiscovery() {
        if (isEnabled()) {
            if (mAdapter != null) {
                mAdapter.cancelDiscovery();
            }
        }
    }

    /**
     * Whether Local Bluetooth Device is enabled
     *
     * @return true if enabled,false otherwise
     */
    public boolean isEnabled() {
        if (isEnable) {
            if (mAdapter != null && !mAdapter.isEnabled()) {
                isEnable = mAdapter.enable();
            }
        }
        return isEnable;
    }

    /**
     * Enable or disable the local Bluetooth device.
     *
     * @param enabled true to enable,false to disable
     */
    public void setEnabled(final boolean enabled) {
        if (isEnabled() == enabled) {
            return;
        }
        isEnable = enabled;
        if (enabled) {
            if (mAdapter != null && !mAdapter.isEnabled()) {
                mAdapter.enable();
            }
        }
    }

    /**
     * Get devices that connected now
     *
     * @return connected devices List
     */
    public List<BluetoothIBridgeDevice> getCurrentConnectedDevice() {
        List<BluetoothIBridgeDevice> devicesList = null;
        devicesList = mConnManager.getCurrentConnectedDevice();
        return devicesList;
    }

    /**
     * Get the last connected device.
     *
     * @return A device which is the last connected.
     */
    public BluetoothIBridgeDevice getLastConnectedDevice() {
        BluetoothIBridgeDevice device = null;
        SharedPreferences sp = mContext.getSharedPreferences(LAST_CONNECTED_DEVICE, Activity.MODE_PRIVATE);

        if (sp != null) {
            String deviceAddress = sp.getString(LAST_CONNECTED_DEVICE_ADDRESS, "");
            if (deviceAddress != null && deviceAddress != "" && deviceAddress != " ") {
                device = BluetoothIBridgeDevice.createBluetoothIBridgeDevice(deviceAddress);
            }
        }
        return device;
    }

    /**
     * Set the current connected device as the last connected device next time
     *
     * @param device the current connected device
     */
    public boolean setLastConnectedDevice(BluetoothIBridgeDevice device) {
        SharedPreferences sp = mContext.getSharedPreferences(LAST_CONNECTED_DEVICE, Activity.MODE_PRIVATE);
        Editor editor = sp.edit();
        editor.putString(LAST_CONNECTED_DEVICE_NAME, device.getDeviceName());
        editor.putString(LAST_CONNECTED_DEVICE_ADDRESS, device.getDeviceAddress());
        boolean flag = editor.commit();
        return flag;
    }

    /**
     * clear all the record of the last connected deivce
     */
    public boolean clearLastConnectedDevice() {
        SharedPreferences sp = mContext.getSharedPreferences(LAST_CONNECTED_DEVICE, Activity.MODE_PRIVATE);
        boolean flag = false;
        if (sp != null) {
            Editor editor = sp.edit();
            editor.clear();
            flag = editor.commit();
        }
        return flag;
    }

    /**
     * Start the listening service
     *
     * @return whether the device is valid.
     */
    public void listen() {
        if (isEnabled()) {
            if (mConnManager != null) {
                mConnManager.listen();
            }
        }
    }

    /**
     * Attempt to connect to a remote device. This method will block until a
     * connection is made or the connection fails. If connect successfully or
     * failed, the registered EventReceiver’s <b>onDeviceConnected</b> or
     * <b>onDeviceConnectFailed</b> will be called respectively.
     *
     * @param device the target BluetoothIBridgeDevice which is to connect.The
     *               BluetoothIBridgeDevice object can be obtained from the
     *               EventReceiver’s onDeviceFound callback or be created by
     *               specifying the Bluetooth Address.
     * @return whether the device is valid.
     */
    public boolean connect(BluetoothIBridgeDevice device) {
        return connect(device, 20);
    }

    public boolean connect(BluetoothIBridgeDevice device, int timeout) {
        if (!isEnabled()) {

            return false;
        }
        if (null == device || null == mConnManager) {

            return false;
        }
        if (!device.isValidDevice()) {
            Logger.v("BluetoothIBridgeAdapter", "+++++++++++++++" + "[" + Thread.currentThread().getName()
                    + "] Unknown device!!!");
            return false;
        } else {
            mConnManager.connect(device, timeout);


            return true;
        }
    }

    /**
     * Attempt to disconnect to a connected device. If the remote device has
     * been disconnected successfully, the registered EventReceiver’s
     * <b>onDeviceDisconnected</b> will be called.
     *
     * @param device the device which is connected but now try to disconnect.
     */
    public void disconnect(BluetoothIBridgeDevice device) {
        if (isEnabled()) {
            if (null == device || null == mConnManager) {
                return;
            }
            mConnManager.disconnect(device);
        }
    }

    /**
     * Send data bytes to target device.
     *
     * @param device the target device to send to.
     * @param buffer the data bytes to send.
     * @param length the length of bytes.
     */
    public void send(BluetoothIBridgeDevice device, byte[] buffer, int length) {
        if (isEnabled()) {
            if (null == device || null == mConnManager) {
                return;
            }
            mConnManager.write(device, buffer, length);
        }
    }

    /**
     * It's called to notify the BluetoothIBridgeAdapter is no longer used and
     * is being removed. The BluetoothIBridgeAdapter should clean up any
     * resources it holds at this point.
     */
    public void destroy() {
        if (mConnManager != null) {
            syncSmartConnectModes(mConnManager.getSmartConnectModes());
            mConnManager.destroy();
            mConnManager = null;
        }
        if (mContext != null) {
            mContext.unregisterReceiver(mReceiver);
        }
        mContext = null;
        sAdapter = null;
    }

    /**
     * Get the friendly Bluetooth name of the local Bluetooth adapter. This name
     * is visible to remote Bluetooth devices.
     *
     * @return the Bluetooth name, or null on error.
     */
    public String getLocalName() {
        if (mAdapter != null) {
            return mAdapter.getName();
        }
        return null;
    }

    /**
     * Set the friendly Bluetooth name of the local Bluetooth adapter. This name
     * is visible to remote Bluetooth devices.
     *
     * @param name a valid Bluetooth name.
     * @return true if the name was set, false otherwise.
     */
    public boolean setLocalName(String name) {
        if (mAdapter != null) {
            return mAdapter.setName(name);
        }
        return false;
    }

    /**
     * Set whether the link key of the connection should be authenticated. If
     * you need to connect devices that without input/output(no keyboard or
     * screen), you can call this method with <b>authenticated</b> set to false.
     * <p>
     * The default value is true to ensure the link key is authenticated.
     *
     * @param authenticated whether the link key should be authenticated
     */
    public void setLinkKeyNeedAuthenticated(boolean authenticated) {
        if (mConnManager != null) {
            mConnManager.setLinkKeyNeedAuthenticated(authenticated);
        }
    }

    public void setConnectMode(ConnectMode mode) {
        if (mConnManager != null) {
            mConnManager.setConnectMode(mode);
        }
    }

    /**
     * Set whether auto bond to device before connect. The default value is true
     * to auto bond.
     *
     * @param auto whether auto bond to device before connect
     */
    public void setAutoBondBeforConnect(boolean auto) {
        if (mConnManager != null) {
            mConnManager.setAutoBond(auto);
        }
    }

    /**
     * Set the Bluetooth is discoverable or not. If bDiscovery is ture , the
     * Bluetooth can be discovered in 120s.
     *
     * @param bDiscoverable true if the Bluetooth is discoverable, false otherwise.
     */
    public void setDiscoverable(boolean bDiscoverable) {
        if (isEnabled()) {
            int duration = bDiscoverable ? 120 : 1;
            if (bDiscoverable) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, duration);
                mContext.startActivity(discoverableIntent);
            } else {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 1);
                mContext.startActivity(discoverableIntent);
            }
        }
    }

    static class MyHandler extends Handler {
        static final String BUNDLE_EXCEPTION = "exception";
        private final WeakReference<BluetoothIBridgeAdapter> mAdapter;

        public MyHandler(BluetoothIBridgeAdapter adapter) {
            mAdapter = new WeakReference<BluetoothIBridgeAdapter>(adapter);
        }

        @Override
        public void handleMessage(Message msg) {
            String exceptionMessage = null;
            Bundle bundle = msg.getData();
            if (bundle != null) {
                exceptionMessage = bundle.getString(MyHandler.BUNDLE_EXCEPTION);
            }

            BluetoothIBridgeAdapter adapter = mAdapter.get();
            log("receive message:" + BluetoothIBridgeAdapter.messageString(msg.what));

            final BluetoothIBridgeDevice device = (BluetoothIBridgeDevice) msg.obj;
            if (adapter != null) {
                adapter.onEventReceived(msg.what, device, exceptionMessage);
            }
            super.handleMessage(msg);
        }
    }

    //?????????????
    private final class InetBroadcastReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            String exceptionMessage = null;
            String action = intent.getAction();
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                exceptionMessage = bundle.getString(MyHandler.BUNDLE_EXCEPTION);
            }
            // ???????????????????豸   ??????????????豸????????????
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (dev.getAddress().matches(devicePattern)) {//devicePattern == .*
                    // BluetoothIBridgeDeviceFactory.getDefaultFactory().createDevice(dev)?ж???????????????豸??????????????豸?б?
                    onEventReceived(MESSAGE_DEVICE_FOUND, BluetoothIBridgeDeviceFactory.getDefaultFactory()
                            .createDevice(dev), exceptionMessage);
                }

            }
            if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                onEventReceived(MESSAGE_DISCOVERY_FINISHED, null, exceptionMessage);
            }
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                switch (state) {
                    case BluetoothAdapter.STATE_ON:
                        break;
                    case BluetoothAdapter.STATE_OFF:
                        break;
                }
            }
            if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                BluetoothIBridgeDevice device = BluetoothIBridgeDeviceFactory.getDefaultFactory().createDevice(dev);
                if (device != null) {
                    device.setBondStatus();
                }
                if (device.getBondStatus() == BondStatus.STATE_BONDED)

                    onEventReceived(MESSAGE_DEVICE_BONDED, null, exceptionMessage);
            }
            if (action.equals(BluetoothIBridgeDevice.ACTION_PAIRING_REQUEST)) {
                BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                BluetoothIBridgeDevice device = BluetoothIBridgeDeviceFactory.getDefaultFactory().createDevice(dev);
                int type = intent.getIntExtra(BluetoothIBridgeDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
                int pairingKey = 0;
                if (type == BluetoothIBridgeDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION
                        || type == BluetoothIBridgeDevice.PAIRING_VARIANT_DISPLAY_PASSKEY
                        || type == BluetoothIBridgeDevice.PAIRING_VARIANT_DISPLAY_PIN) {
                    pairingKey = intent.getIntExtra(BluetoothIBridgeDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
                }
                if (isAutoWritePincode) {
                    if (mConnManager != null) {
                        mConnManager.onPairingRequested(device, type, pairingKey);

                    }
                }
            }
            if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {

            }
            if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {

            }
        }
    }

    private static String messageString(int message) {
        switch (message) {
            case MESSAGE_DEVICE_CONNECTED:
                return "MESSAGE_DEVICE_CONNECTED";
            case MESSAGE_DEVICE_DISCONNECTED:
                return "MESSAGE_DEVICE_DISCONNECTED";
            case MESSAGE_DEVICE_CONNECT_FAILED:
                return "MESSAGE_DEVICE_CONNECT_FAILED";
            case MESSAGE_DEVICE_FOUND:
                return "MESSAGE_DEVICE_FOUND";
            case MESSAGE_DISCOVERY_FINISHED:
                return "MESSAGE_DISCOVERY_FINISHED";
            case MESSAGE_DEVICE_BONDED:
                return "MESSAGE_DEVICE_BONDED";
            case MESSAGE_WRITE_FAILED:
                return "MESSAGE_WRITE_FAILED";
        }
        return "MESSAGE";
    }

    private void onEventReceived(int what, BluetoothIBridgeDevice device, String exceptionMessage) {
        log("onEventReceived(" + what + ")");
        if (mEventReceivers != null) {
            @SuppressWarnings("unchecked")
            ArrayList<EventReceiver> listenersCopy = (ArrayList<EventReceiver>) mEventReceivers.clone();
            int numListeners = listenersCopy.size();
            for (int i = 0; i < numListeners; ++i) {
                EventReceiver er = listenersCopy.get(i);
                switch (what) {
                    case MESSAGE_DEVICE_BONDED:
                        er.onDeviceBonded(device);
                        break;
                    case MESSAGE_DEVICE_CONNECTED:

                        er.onDeviceConnected(device);
                        break;
                    case MESSAGE_DEVICE_DISCONNECTED:
                        er.onDeviceDisconnected(device, exceptionMessage);
                        break;
                    case MESSAGE_DEVICE_CONNECT_FAILED:
                        er.onDeviceConnectFailed(device, exceptionMessage);
                        break;
                    case MESSAGE_DEVICE_FOUND:
                        boolean notifyFound = (device != null);
                        if (mDiscoveryOnlyBonded) {
                            if (notifyFound) {
                                notifyFound = device.isBonded();//?ж??豸??????
                            }
                        }
                        if (notifyFound) {
                            er.onDeviceFound(device);
                        }
                        break;
                    case MESSAGE_DISCOVERY_FINISHED:
                        er.onDiscoveryFinished();
                        break;
                    case MESSAGE_WRITE_FAILED:
                        er.onWriteFailed(device, exceptionMessage);
                        break;
                }
            }
        }
    }

    /**
     * Get iBridge version code
     *
     * @return version_code
     */
    public static String getVersion() {
        return VERSION_CODE;
    }

    static void log(String content) {
        Logger.v(TAG, "+++++++++++++++" + "[" + Thread.currentThread().getName() + "] " + content);
    }

    /**
     * Set the pattern of the device name
     *
     * @param devicePattern the pattern to set
     */
    public void setDevicePattern(String devicePattern) {
        this.devicePattern = devicePattern;
    }

    /**
     * Set Pincode, default 0000.
     *
     * @param pincode 0000 or 1234 commonly
     */
    public void setPincode(String pincode) {
        if (mConnManager != null)
            mConnManager.setPincode(pincode);
    }

    /**
     * Set auto write pincode when receiving pairing request.
     *
     * @param auto true if auto write , other false
     */
    public void setAutoWritePincode(boolean auto) {
        isAutoWritePincode = auto;
    }

    private void saveSmartConnectModes(ConnectMode[] modes) {
        try {
            StringBuffer str = new StringBuffer();
            for (int i = 0; i < modes.length; i++) {
                str.append(modes[i].toString());
                if (i != modes.length - 1) {
                    str.append(",");
                }
            }
            FileOutputStream fos = mContext.openFileOutput("SmartConnectModes", Context.MODE_PRIVATE);
            fos.write(str.toString().getBytes());
            fos.close();
        } catch (Exception e) {
            BluetoothIBridgeAdapter.log(e.getMessage());
        }
    }

    private void syncSmartConnectModes(ConnectMode[] modes) {
        ConnectMode[] readModes = null;
        List<ConnectMode> modeList = new ArrayList<ConnectMode>();
        try {
            FileInputStream fis = mContext.openFileInput("SmartConnectModes");
            byte buf[] = new byte[fis.available()];
            if (fis.read(buf) != -1) {
                String str = new String(buf);
                for (String strMode : str.split(",")) {
                    modeList.add(ConnectMode.valueOf(strMode));//??????????
                }
            }
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (modeList.size() == 0) {//???modelist size?0
            saveSmartConnectModes(BluetoothIBridgeConnManager.DefaultConnectModes);//????????????????connectmode????????
            readModes = BluetoothIBridgeConnManager.DefaultConnectModes;
        } else {
            readModes = (ConnectMode[]) modeList.toArray(new ConnectMode[modeList.size()]);
        }
        if (mConnManager != null && readModes != null) {
            if (modes == null) {//????????????null????????????????????????
                mConnManager.setSmartConnectModes(readModes);
            } else {
                for (int i = 0; i < modes.length; i++) {//???????modes??????????readmodes???????????modesд?????
                    if (modes[i] != readModes[i]) {
                        saveSmartConnectModes(modes);
                        break;
                    }
                }
            }
        }
    }
}
